<!--author:adminj-->
<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>AdminJ FormDesigner</title>
    <link rel="stylesheet" href="libs/layui/css/layui.css?v=1">
    <link rel="stylesheet" href="libs/select2/css/select2.min.css">
    <style>


        .upload_ul {
            border: dashed 0px #009;
        }

        .upload_ul li {
            list-style-type: none;
            float: left;
            display: inline;
            border: dashed 1px #009;
            list-style: none;
            margin: 5px;
            padding: 0px;
        }

        .upload_tools_div {
            display: block;
            position: absolute;
            pointer-events: none;
            border: solid coral 0px;
        }

        .upload_image_style {
            width: 100px;
            height: 80px;
        }


        .list li {
            list-style-type: none;
            float: left;
            display: inline;
            border: dotted 1px #009;
            list-style: none;
            margin: 0px;
            padding: 0px;
        }


        .layui-form-item {
            margin-bottom: 10px;
            clear: both;
            *zoom: 1;
        }

        /*.layui-form-radio {*/
        /*    line-height: 28px;*/
        /*    margin: 6px 0px 0 0;*/
        /*    padding-right: 5px;*/
        /*    cursor: pointer;*/
        /*    font-size: 0;*/
        /*}*/

        .select2-container--default .select2-selection--multiple .select2-selection__choice {
            background-color: #337ab7;
            border: 1px solid #1d6fa5;
            color: #fff;
            border-radius: 4px;
            cursor: default;
            float: left;
            margin-right: 5px;
            margin-top: 5px;
            padding: 3px 5px;
        }

        .select2-container--default .select2-selection--multiple .select2-selection__choice__remove {
            color: rgba(255, 255, 255, .7);
            float: right;
            margin-left: 5px;
            margin-right: -2px;
        }

        .select2-container .select2-search--inline {
            float: left;
            border: none;
        }

        .select2-container--default .select2-selection--multiple {
            background-color: white;
            border: 1px solid #eee;
            border-radius: 4px;
            cursor: text;
            min-height: 38px;
        }

    </style>
    <!--框架CSS START-->
    <style>
        .adminj-sort-item {

        }
        .propertiesdiv_sp {
            font-size: 12px;
            color: #6e7479;
            margin-top: 10px;
            margin-bottom: 0px;
        }
        .propertiesdiv_sp input {
            height: 30px;
        }
        .left_darg_button {
            width: 93%;
            cursor: move;
            border: dashed 1px #c7ced5;
            margin-top: 3px;
            height: 30px;
            line-height: 30px;
        }
        .mouse-hover-color {
            border: dashed 1px cornflowerblue;
        }

        .select-sort-item {
            position: relative;
            border: dashed 1px cornflowerblue;
            /*pointer-events: none;*/
        }

        .group-layout-item {
            /*padding-top: 10px;*/
            min-height: 38px;
        }

        .group-layout-border {
            border: dashed 1px #c7ced5;
            min-height: 38px;
        }

        .item-bottom-right-tools {
            position: absolute;
            height: 23px;
            line-height: 23px;
            background: #1d6fa5;
            right: 0;
            bottom: 0;
            cursor: pointer;
            z-index: 21;
            color: #fff;
        }

        .item-top-left-tools {
            position: absolute;
            line-height: 20px;
            background: #1d6fa5;
            left: 0;
            top: 0;
            cursor: pointer;
            z-index: 20;
            color: #fff;
            font-size: 11px;
        }


        .ds-left{
            width:250px;padding-left: 5px;
            list-style-type: none;
            float: left;
            display: inline;
            border: dashed 0px #009;
            list-style: none;
            margin: 5px;
            padding: 0px;
            position: absolute;
            top:36px;
        }
        .ds-center{
            margin-top: 5px;
            float: left;
            border: dashed cadetblue; padding: 3px;
            list-style-type: none;
            left:260px;
            right:275px;
            min-height:800px;
            position: absolute;
            top:36px;
        }
        .ds-right{
            float: left;
            width: 260px; padding-top: 10px; padding-bottom: 10px; padding-left: 10px; min-height:500px;
            list-style-type: none;
            right:0px;
            position: absolute;
            top:36px;
        }
        .ds-top-right{
            margin-top: 5px;width:100%; text-align: right;
            position: absolute;
            right: 270px;
        }

        .ds-top-left {
            float: left;
            padding-left: 20px;
            line-height: 36px;
            position: absolute;
            font-weight: bold;
            font-size: 15px;
        }
    </style>
    <script src="libs/layui/layui.js?2.6.8"></script>
    <script src="libs/jquery/jquery-3.6.0.min.js"></script>
    <script src="libs/sortable/sortable.min.js"></script>
    <script src="libs/sortable/jquery-sortable.js"></script>
    <script src="libs/select2/js/select2.full.min.js"></script>
    <script src="libs/ckeditor5/ckeditor.js"></script>

    <script src="adminj/adminj_utils.js"></script>

</head>
<body>
<form action="browse.jsp" method="post" target="_blank id="browseResultForm">
    <input type="hidden" name="resHtml" id="resHtml" /><input type="submit" name="button" id="submitHtml" value="提交" style="display: none;" />
</form>

<form class="layui-form" id="form" lay-filter="form" action="">
        <div class="ds-top-left">AdminJ LayuiFormRender</div>
        <div  class="ds-top-right">
            <button type="button" class="layui-btn layui-btn-sm" lay-filter="export" id="exportForm">
                <i class="layui-icon layui-icon-download-circle" style="font-size: 1.2em" ></i> 导出HTML代码
            </button>
            <button type="button" class="layui-btn layui-btn-sm" lay-filter="exportJSON" id="exportJSON">
                <i class="layui-icon layui-icon-download-circle" style="font-size: 1.2em"></i> 导出JSON
            </button>
            <button type="button" class="layui-btn layui-btn-sm" lay-filter="itemJson" id="itemJson">
                <i class="layui-icon layui-icon-download-circle" style="font-size: 1.2em"></i> 当前选择项JSON
            </button>
            <button type="button" class="layui-btn layui-btn-sm" lay-filter="exportJSON" id="importJSON">
                <i class="layui-icon layui-icon-upload-drag" style="font-size: 1.2em"></i> 导入JSON
            </button>
            <button type="button" class="layui-btn layui-btn-sm" lay-filter="browseResult" id="browseResult">
                <i class="layui-icon layui-icon-website" style="font-size: 1.2em"></i> 预览
            </button>
        </div>


    <ul><li class="ds-left" id="leftButtons"></li><li class="ds-center" id='sortable'></li><li class="ds-right">

        <div class="layui-tab layui-tab-brief">
            <ul class="layui-tab-title">
                <li class="layui-this">属性设置</li>
            </ul>
            <div class="layui-tab-content" style="height: 100px;">
                <div class="layui-tab-item layui-show" id="propertiesDiv" style="padding-bottom: 20px;"></div>
            </div>
        </div>

    </li></ul>

</form>


<!--所有的组件 display:block 后可以直接在浏览器修改预览-->
<span id="cpts_items" style="display: none">
        <div class="layui-form-item adminj-sort-item" id="text">
                            <label class="layui-form-label">text</label>
                            <div class="layui-input-inline" style="width:60%;">
                                <input type="text" name="" autocomplete="off" class="layui-input" style="width: 99%;">
                            </div>
            <div class="layui-form-mid layui-word-aux"></div>
        </div>
        <div class="layui-form-item adminj-sort-item group-layout-border" id="hidden">
                            <label class="layui-form-label">&nbsp;</label>
                            <div class="layui-input-inline" style="width:60%;">
                                <input type="hidden" name="">
                            </div>
            <div class="layui-form-mid layui-word-aux"></div>
        </div>
        <div class="layui-form-item adminj-sort-item" id="password">
                            <label class="layui-form-label">password</label>
                            <div class="layui-input-inline" style="width:60%;">
                                <input type="password" name="" autocomplete="off" class="layui-input"
                                       style="width: 99%;">
                            </div>
            <div class="layui-form-mid layui-word-aux"></div>

        </div>

        <div class="layui-form-item adminj-sort-item" id="textarea">
                            <label class="layui-form-label">textarea</label>
                            <div class="layui-input-inline" style="width:60%;">
                                <textarea class="layui-textarea" name="textarea" style="width: 99%;"></textarea>
                            </div>


        </div>

        <div class="layui-form-item adminj-sort-item" id="date">
            <label class="layui-form-label">日期选择</label>
            <div class="layui-input-inline">
              <input type="text" name="" class="layui-input">
            </div>
            <div class="layui-form-mid layui-word-aux"></div>

        </div>

        <div class="layui-form-item adminj-sort-item" id="switch" rename="false">
        <label class="layui-form-label">开关</label>
        <div class="layui-input-inline">
          <input type="checkbox" checked="" name="" lay-skin="switch" lay-filter="switch" lay-text="ON|OFF">
        </div>
            <div class="layui-form-mid layui-word-aux"></div>

      </div>

        <div class="layui-form-item adminj-sort-item" id="select">
        <label class="layui-form-label">下拉选项</label>
        <div class="layui-input-inline">
          <select name="">
            <option value="0" selected="">选择</option><option value="1">选项2</option><option value="2">选项3</option>
          </select>
        </div>
            <div class="layui-form-mid layui-word-aux"></div>

      </div>

    <div class="layui-form-item adminj-sort-item" id="select2" rename="false">
        <label class="layui-form-label" style="margin-top: -3px;">下拉多选</label>
        <div class="layui-input-inline" style="width:60%;">
                <select name="" lay-ignore class="select2" multiple="multiple" data-placeholder=""
                        data-dropdown-css-class="select2-purple" style="width: 99%;">
                        <option value="0" selected="">选择</option><option value="1">选项2</option><option value="2">选项3</option>
                </select>
        </div>

    </div>

    <div class="layui-form-item adminj-sort-item" id="radio">
        <label class="layui-form-label">单选择框</label>
        <div class="layui-input-inline" style="width:60%;">
            <input name="" type="radio" value="0" index="0" checked="" title="选择" lay-skin="primary">
            <input name="" type="radio" value="1" index="1" title="选项2" lay-skin="primary">
            <input name="" type="radio" value="2" index="2" title="选项3" lay-skin="primary">
    </div>
    <div class="layui-form-mid layui-word-aux"></div>
    </div>

    <div class="layui-form-item adminj-sort-item" id="checkbox">
        <label class="layui-form-label">多选择框</label>
        <div class="layui-input-inline" style="width:60%;">
            <input name="" type="checkbox" value="0" index="0" checked="" title="选择" lay-skin="primary">
            <input name="" type="checkbox" value="1" index="1" title="选项2" lay-skin="primary">
            <input name="" type="checkbox" value="2" index="2" title="选项3" lay-skin="primary">
        </div>
        <div class="layui-form-mid layui-word-aux"></div>
    </div>


     <div class="layui-form-item adminj-sort-item" id="dateRange">
         <label class="layui-form-label">日期范围</label>
        <div class="layui-input-inline">
          <input type="text" autocomplete="off" class="layui-input">
        </div>
        <div class="layui-form-mid layui-word-aux"></div>
    </div>

    <div class="layui-form-item adminj-sort-item" id="uploadImage" rename="false">
      <label class="layui-form-label">单图上传</label>
        <div class="layui-input-inline">
            <!--button type="button" class="layui-btn" id="uploadbutf"><i class="layui-icon"></i>上传图片</button-->
            <ul class="upload_ul">
               <li style="border: 0px;">

                <div class="upload_image_style" update_width="true">
                <div class="upload_image_style" style="position:relative;top:0%;" flag="upload_div">
                  <div class="layui-upload-list" style="text-align: center;line-height: 60px;">
                      <i class="layui-icon layui-icon-upload-drag" style="font-size: 1.8em;color: #1d6fa5;"></i>
                    <p id="msgText" style="display: none"></p>
                  </div>
                  <div id="upload_bar_div" style="top:25%;width: 100%; display: none;position:absolute;"
                       update_width="true">
                    <div class="layui-progress layui-progress-big" lay-showpercent="yes" lay-filter="layui-progress">
                      <div class="layui-progress-bar" lay-percent=""></div>
                    </div>
                  </div>
                 </div>
                 <div class="upload_image_style" id="upload_image_div"
                      style="top:5px;position:absolute;border:dashed 1px;pointer-events: none;" update_width="true">
                         <img class="layui-upload-img"
                              style="wdith:100%;height: 100px;pointer-events: none;display: none;" id="image_src">
                 </div>
                  <div class="upload_image_style" id="upload_mask_div"
                       style="top:0%;position:absolute;pointer-events: auto; display: none" update_width="true">

                 </div>
                </div>

           </li></ul>

        </div>
        <div class="layui-form-mid layui-word-aux"></div>


    </div>

    <div class="layui-form-item adminj-sort-item" id="uploadImages" rename="false">
      <label class="layui-form-label">多图上传</label>
        <div class="layui-input-inline" style="width:80%;">
           <ul class="upload_ul">
               <li>
                        <div class="upload_image_style" update_width="true">
                            <div class="upload_image_style" style="position:absolute;z-index: 597;" flag="upload_div">
                              <div class="layui-upload-list" style="text-align: center;line-height: 60px;">
                                  <i class="layui-icon layui-icon-upload-drag" style="font-size: 1.8em;color: #1d6fa5;"></i>
                                <p id="msgText" style="display: none"></p>
                              </div>
                              <div id="upload_bar_div" style="top:35%;width: 100%; display: none;position:absolute;"
                                   update_width="true">
                                <div class="layui-progress layui-progress-big" lay-showpercent="yes"
                                     lay-filter="layui-progress">
                                  <div class="layui-progress-bar" lay-percent=""></div>
                                </div>
                              </div>
                            </div>
                         <div class="upload_image_style" id="upload_image_div"
                              style="position:absolute;z-index: 598;border:dashed 0px red;pointer-events: none;"
                              update_width="true">
                                 <img class="layui-upload-img"
                                      style="wdith:100%;height: 100px;pointer-events: none;display: none;"
                                      id="image_src">
                         </div>
                          <div class="upload_image_style" id="upload_mask_div"
                               style="position:absolute;z-index: 599;pointer-events: auto; display: none"
                               update_width="true">

                         </div>

                         <div id="close_div" class="upload_tools_div upload_image_style"
                              style="pointer-events: none;position:absolute;z-index: 600;border:dotted 0px red; "
                              update_width="true">
                        <div style="position:absolute;pointer-events: auto;cursor:pointer;background-color:#1d6fa5;top:-8px;right: -10px;border-radius:10px;height: 18px;width: 18px;line-height: 18px;">
                            <i class="layui-icon layui-icon-close" style="font-size: 15px; color:#ffffff;padding: 1px;"></i>
                        </div>
                        </div>

                        </div>


               </li>

               <li id="add_div" class="upload_image_style" style=" border: dashed 1px #1d6fa5;text-align: center">
                   <span class="layui-icon layui-icon-add-circle-fine" style="font-size: 2em; color: #1d6fa5;line-height: 80px;"></span>
               </li>

           </ul>

        </div>


    </div>


    <div class="layui-form-item adminj-sort-item" id="uploadFile" rename="false">
      <label class="layui-form-label">上传文件</label>
        <div class="layui-input-inline">
          <button type="button" class="layui-btn" id="uploadFile"><i class="layui-icon"></i>上传文件<li id="uploaded_div"
                                                                                                     style="border: 0px;"></li></button>
        </div>
        <div class="layui-form-mid layui-word-aux"></div>


    </div>


    <div class="layui-form-item adminj-sort-item" id="uploadFiles" rename="false">
        <label class="layui-form-label">多文件上传</label>
        <div class="layui-input-block">
        <div class="layui-upload">
          <button type="button" class="layui-btn" select_file="true">选择多文件</button>
            <button type="button" class="layui-btn" upload_file="true"><i class="layui-icon"></i>上传文件</button>
          <div class="layui-upload-list" style="max-width: 1000px;">
            <table class="layui-table">
              <colgroup>
                <col>
                <col width="150">
                <col width="260">
                <col width="150">
              </colgroup>
              <thead>
                <tr><th>文件名</th>
                <th>大小</th>
                <th>上传进度</th>
                <th>操作</th>
              </tr></thead>
              <tbody id="fileList"></tbody>
            </table>
          </div>
            <!--button type="button" class="layui-btn" id="uploadListAction">开始上传</button-->
        </div>
    </div>

    </div>


    <div class="layui-form-item adminj-sort-item" id="color">
      <label class="layui-form-label">颜色选择</label>
        <div class="layui-input-inline">
           <input type="text" value="" placeholder="" class="layui-input">
        </div>
        <div class="layui-inline">
        <div flag="color_ui_div"></div>
      </div>


    </div>

    <div id="submitData" class="layui-form-item adminj-sort-item" rename="false">
    <div class="layui-input-block">
      <button type="submit" class="layui-btn" lay-submit="" lay-filter="postButton" id="postButton">立即提交</button>
      <button type="reset" class="layui-btn layui-btn-primary">重置</button>
    </div>

  </div>

    <div class="layui-form-item layui-row  adminj-sort-item" id="groupLayout" rename="false">
        <div class="adminj-col-item group-layout-border layui-col-md6">
        </div>
        <div class="adminj-col-item group-layout-border layui-col-md6">
        </div>
    </div>


    <div class="layui-form-item adminj-sort-item" id="slider">
      <label class="layui-form-label">滑块</label>
        <div class="layui-input-inline" style="width: 60%;">
            <div style="margin-left: 10px; margin-bottom: 18px; margin-top: 18px;"></div>
        </div>
        <div class="layui-form-mid layui-word-aux"></div>
    </div>


    <div class="layui-form-item adminj-sort-item" id="rate">
      <label class="layui-form-label">评分</label>
        <div class="layui-input-inline" style="width: 60%;">
            <div style="margin-left: 10px; "></div>
        </div>
        <div class="layui-form-mid layui-word-aux"></div>
    </div>

    <div class="layui-form-item adminj-sort-item" id="selectS">
        <label class="layui-form-label">无限级联动</label>
          
          <div class="layui-form-mid layui-word-aux"></div>
    </div>


    <div class="layui-form-item adminj-sort-item" id="editor">
                            <label class="layui-form-label">文本编辑器</label>
                            <div class="layui-input-block" style="width:88%;  ">
                                <div class="editor">
							<h2>Bilingual Personality Disorder</h2>
							<figure class="image image-style-side"><img
                                    src="https://c.cksource.com/a/1/img/docs/sample-image-bilingual-personality-disorder.jpg">
								<figcaption>One language, one person.</figcaption>
							</figure>
							<p>
								adults who are bilingual in English in French were showed series of pictures and were asked to create 3-minute stories.
								In the end participants emphasized drastically different dynamics for stories in English and French.
							</p>
							<p>
								Another ground-breaking experiment which included bilingual Japanese women married to American men in San Francisco were
								asked to complete sentences. The goal of the experiment was to investigate whether or not human feelings and thoughts
								are expressed differently in <strong>different language mindsets</strong>.
								<Here>is a sample from the the experiment:</Here>
							</p>
							<table>
								<thead>
									<tr>
										<th></th>
										<th>English</th>
										<th>Japanese</th>
									</tr>
								</thead>
								<tbody>
									<tr>
										<td>Real friends should</td>
										<td>Be very frank</td>
										<td>Help each other</td>
									</tr>
									<tr>
										<td>I will probably become</td>
										<td>A teacher</td>
										<td>A housewife</td>
									</tr>
								</tbody>
							</table>
							<p>
								More recent <a href="https://books.google.pl/books?id=1LMhWGHGkRUC">studies</a> show, the language a person speaks affects
								their cognition, behaviour, emotions and hence <strong>their personality</strong>.
								This shouldn’t come as a surprise
								<a href="https://en.wikipedia.org/wiki/Lateralization_of_brain_function">since we already know</a> that different regions
								of the brain become more active depending on the person’s activity at hand. Since structure, information and especially
								<strong>the culture</strong> of languages varies substantially and the language a person speaks is an essential element of daily life.
							</p>
						</div>
                   </div>
        </div>


</span>


<!--layui template生成左边的拖放button-->
<script id="leftButtonTemplate" type="text/html">

    {{#  layui.each(d.list, function(i, groups){ }}

    <div class="layui-tab layui-tab-brief">
        <ul class="layui-tab-title">
            <li class="layui-this">{{ groups.groupName }}</li>
        </ul>
        <div class="layui-tab-content">
            <div class="layui-tab-item layui-show">
                <div class="layui-row">
                    {{# layui.each(groups.list, function(index, item){ }}
                    <div class="layui-col-xs6">
                        <div>
                            <button type="button" cpt_id="{{ item.id }}"
                                    class="layui-btn layui-btn-primary left_darg_button">{{ item.name }}
                            </button>
                        </div>
                    </div>
                    {{# }); }}
                </div>
            </div>
        </div>
    </div>

    {{#  }); }}


</script>
<!--点击中间组件后出现的删除和复制工具条-->
<script id="toolsTemplate" type="text/html">
    <div class="action-tools item-top-left-tools">
        &nbsp;&nbsp;<i class="layui-icon layui-icon-screen-full"></i>&nbsp;&nbsp;
    </div>
    <div class="action-tools item-bottom-right-tools">
        &nbsp;&nbsp;<i class="layui-icon layui-icon-delete"></i>&nbsp;&nbsp;
        <i class="layui-icon layui-icon-layer"></i>&nbsp;&nbsp;
    </div>
</script>
</body>
</html>


<script>

/**
 * 开源不易，如果可能请留下版权信息
 * @auther adminj
 * @date 2021-7
 * @version 1.1
 **/

    function AdminJLayuiFormRender() {
        this.propertiesMap={};
        this.config={dragName: "adminjForm",defaultLabelWidth:80,
        ajaxRequestName:{
                resultCodeName:'resultCode',
            messageName:'message',
            resultName:'result'
        }};
    }

    AdminJLayuiFormRender.prototype.isEmpty=function (str) {
        return str==undefined || str.length==0;
    }
    AdminJLayuiFormRender.prototype.render = function () {
        this.components = this.initInputComponents();
        this.rightPropertiesComponents = this.initRightPropertiesComponents();
        this.initLeftUI();

        this.createSortable('sortable', {});
    

    }

    AdminJLayuiFormRender.prototype.createSortable = function (id, params) {
        var that=this;
        var draggable = params.draggable;
        if (draggable == undefined) draggable = '.adminj-sort-item';
        //var dv=document.getElementById(id)
        //$('#'+id).sortable({
        //new Sortable(dv,{
        $('#' + id).sortable({
            group: that.config.dragName,
            fallbackOnBody: true,
            swapThreshold: 0.65,
            animation: 150,
            handle: '.layui-icon-screen-full',
            draggable: draggable,
            sort: true,
            onEnd: function (/**Event*/evt) {
                that.createSortableItem(evt);
            }
        });

    }

    AdminJLayuiFormRender.prototype.initLeftUI = function () {//初始化左边的拖动按钮
        var that=this;
        var cpts_base = {
            'text': '输入框',
            'hidden': '隐藏域',
            'password': '密码框',
            'textarea': '文本域',
            'date': '日期选择',
            'switch': '选择开关',
            'select': '下拉选项',
            'select2': '下拉多选',
            'radio': '单选框',
            'checkbox': '多选框',
            'dateRange': '日期范围',
            'color': '颜色选择器',
            'editor': '文本编辑器',
            'slider': '滑块',
            'rate': '评分',
            'selectS': '无限级联动',
            'submitData': '提交数据'
        }
        var cpts_file = {'uploadImage': '单图上传', 'uploadImages': '多图上传', 'uploadFile': '文件上传', 'uploadFiles': '多文件上传'}
        var cpts_layout = {'groupLayout': '多组布局'}
        var cptsGroups = {'基础组件': cpts_base, '文件上传': cpts_file, '布局': cpts_layout};

        var buttonDataList = [];
        var i = 0;
        for (name in cptsGroups) {
            var cptMap = cptsGroups[name];
            var cptArray = [], j = 0;
            for (cptId in cptMap) {
                cptArray[j] = {id: cptId, name: cptMap[cptId]}
                j++;
            }
            buttonDataList[i] = {groupName: name, list: cptArray}
            i++;
        }
        var tlp = $('#leftButtonTemplate').html();
        var html = layui.laytpl(tlp).render({
            list: buttonDataList
        });
        $('#leftButtons').html(html);

        $('#leftButtons').find('.layui-row').each(function (i, e) {
            //for (i = 0; i < subGroup.length; i++) {
            //new Sortable(subGroup[i], {
            $(this).sortable({
                group: {
                    name: that.config.dragName,
                    pull: 'clone',
                    put: false
                },
                animation: 150,
                fallbackOnBody: true,
                swapThreshold: 0.65,
                sort: false,
                onEnd: function (/**Event*/evt) {
                    that.createSortableItem(evt);
                }
            });
            //}
        });
    }


    AdminJLayuiFormRender.prototype.initSortabletemMouseEvent = function (item) {//初始化中间的组件事件
        var that=this;
        item.mouseover(function () {
            if ($(this).hasClass('group-layout-border')) {
                $(this).attr('removeClass', 'group-layout-border');
                $(this).removeClass('group-layout-border');
            }
            $(this).addClass('mouse-hover-color');
        }).mouseout(function () {
            if ($(this).attr('cpt_id') == 'groupLayout') {
                if ($(this).hasClass('select-sort-item')) {//如果被选中了则不恢复
                    return;
                }
                $(this).removeClass('mouse-hover-color');
            } else {
                $(this).removeClass('mouse-hover-color');
                if ($(this).attr('removeClass') != undefined) {
                    $(this).addClass($(this).attr('removeClass'))
                }
            }
        }).click(function () {
            if ($(this).hasClass('select-sort-item')) return;

            $('#sortable').find('.select-sort-item').each(function () {//删除其它选中层
                $(this).removeClass('select-sort-item');
                if ($(this).attr('cpt_id') == 'groupLayout') {
                    //$(this).addClass('group-layout-border');
                    $(this).removeClass('mouse-hover-color');
                }
                $(this).find('.action-tools').each(function (i, e) {
                    $(this).remove();
                });
            });
            //$(this).removeClass('group-layout-border');
            var html = $(layui.laytpl($('#toolsTemplate').html()).render({}));
            $(this).addClass('select-sort-item');
            var id = $(this).attr('id');
            html.find('.item-top-left-tools').addClass(id);
            html.find('.layui-icon-delete').click(function () {//delete
                $('#sortable').find('.select-sort-item').remove();
                $('#propertiesDiv').html('');
            });
            html.find('.layui-icon-layer').click(function () {//copy
                var copyNode = $('#sortable').find('.select-sort-item');
                var copyId = copyNode.attr('id');
                var properties = that.propertiesMap[copyId];
                var newDivId = 'did_' + Date.now() + "_0";
                var resultArray = [];
                that.exportSingleItemJSON(0, copyNode, resultArray);
                var newProperties = JSON.parse(JSON.stringify(resultArray[0]));
                that.propertiesMap[newDivId] = newProperties;
                var params = {index: 0, copyNode: copyNode, divId: newDivId};

                that.createItemBySingleData($('#sortable'), newProperties, params);
            });
            $(this).append(html);

            that.rightPropertiesComponents.render($(this));

            return false;
        });
    }

    AdminJLayuiFormRender.prototype.createSortableItem = function (evt) {//初始化中间的单个组件
        var _class = evt.to.getAttribute('class');
        if (evt.to == undefined || !(evt.to.getAttribute('id') == 'sortable' || (_class != undefined && (_class.indexOf('adminj-sort-item') != -1 || _class.indexOf('adminj-col-item') != -1)))) return;
        var item = $(evt.item);
        if (!item.find('button').hasClass('left_darg_button')) return;
        var divId = 'did_' + Date.now();
        evt.item.setAttribute('id', divId);
        var cptId = '';
        item.find(':input').each(function (i, e) {
            cptId = $(this).attr('cpt_id');
        });
        var html = $($('#cpts_items').find("#" + cptId).get(0).outerHTML);
        html.attr('id', divId + '0').attr('cpt_id', cptId);

        $('#' + divId).after(html);
        $('#' + divId).remove();

        this.createSortableItemUI(html);
        layui.form.render();
    }

    AdminJLayuiFormRender.prototype.createSortableItemUI = function (item, initParams) {//初始化item UI 和 个性化事件
        var that=this;
        var cptId = item.attr('cpt_id');
        var divId = item.attr('id');

        var properties=that.propertiesMap[divId];
        if (properties != undefined) {//init form
            //INIT公共基本参数
            var label=properties['label'];
            var labelWidth=properties['labelWidth'];
            var rowWidth=properties['rowWidth'];
            var inputWidth=properties['inputWidth'];
            var name=properties['name'];
            var comment=properties['comment'];
            var placeholder=properties['placeholder'];
            var defValue=properties['defValue'];

            if(!this.isEmpty(label))item.find('.layui-form-label').html(label);
            if(!this.isEmpty(comment))item.find('.layui-word-aux').html(comment);
            if(!this.isEmpty(labelWidth) && that.config.defaultLabelWidth+''!=labelWidth)item.find('.layui-form-label').css('width',labelWidth+'px');
            if(!this.isEmpty(rowWidth))item.css('width',rowWidth+'%');
            if(!this.isEmpty(inputWidth))item.find('.layui-form-label').next().css('width',inputWidth+'%');
            if(!this.isEmpty(name) && item.attr('rename')!='false')item.find(':input').attr('name',name);
            if(!this.isEmpty(placeholder) && (cptId=='text' || cptId=='textarea' || cptId=='color'))item.find(':input').attr('placeholder',placeholder);
            if(!this.isEmpty(defValue) && (cptId=='text' || cptId=='hidden' || cptId=='password' || cptId=='textarea' || cptId=='color')){
           
                if(cptId=='textarea'){
                    item.find(':input').text(that.htmlDecode(defValue));
                }else{
                    item.find(':input').attr('value',that.htmlDecode(defValue));
                }
            }

        } else {
            var name='name'+new Date().getTime();
            var cptProperties={id: cptId,name:name};
            if(item.attr('rename')!='false'){
                item.find(':input').attr('name',name);
            }
            that.propertiesMap[divId] = cptProperties;
        }
        this.initSortabletemMouseEvent(item);
        this.renderComponent('this.components', item,initParams,function (func,item,initParams) {
            if(initParams==undefined)initParams={};
            func(item,initParams);
        });
    }



    AdminJLayuiFormRender.prototype.initInputComponents = function () {//中间显示的组件
        var that=this;
        var initOptions=function (item,selectedArray,selectedString,optionFunc) {// init option array
                var divId = item.attr('id');
                var properties = that.propertiesMap[divId];
                var arr = properties['options'];
                if (arr != undefined) {
                    var options = '';
                    for (var i = 0; i < arr.length; i++) {
                        var row = arr[i];
                        var selected = '';
                        if(row.isSelect == '0'){
                            selected=selectedString;
                            if(selectedArray!=undefined){
                                selectedArray[selectedArray.length]=row.value;
                            }
                        }
                        options += optionFunc(i,row,selected);
                    }
                    return options;
                }
                return undefined;
            }

        var initSelectOptions=function (item,selectedArray) {// init select option
            var options=initOptions(item,selectedArray,'selected',function(index,option,selectResult){
               return  '<option value="' + option.value + '" ' + selectResult + '>' + option.text + '</option>';
            });
            if(options!=undefined){
                item.find('select').html(options);
            }
        }

        var initRadioOrChecxbox=function (item,inputType) {
            var options = initOptions(item, undefined, 'checked', function (index, option, selectResult) {
                return '<input name="" type="'+inputType+'" value="' + option.value + '" index="' + index + '" ' + selectResult + ' title="' + option.text + '" lay-skin="primary">';
            });
            if (options != undefined) {
                item.find('.layui-form-label').next().html(options);
            }
            var divId = item.attr('id');
            var name = that.propertiesMap[divId]['name'];
            if(!that.isEmpty(name)){
                item.find(':input').attr('name', name);
            }
            
        }

        var initDate=function (item,isRange) {
            var divId = item.attr('id');
            var properties=that.propertiesMap[divId];
            var dateFormat='date';
            if(properties['dateFormat']!=undefined){
                dateFormat=properties['dateFormat'].split('|')[0];
            }
            var dateInputId = divId + 'd_rang';
            item.find(':input').attr('id', dateInputId);
            layui.laydate.render({
                elem: '#' + dateInputId,
                type:dateFormat
                , range: isRange
            });
        }


        var components = {
            renderSwitch: function (item) {
                var divId = item.attr('id');
                var properties = that.propertiesMap[divId];
                var layText = 'NO|OFF';
                if (!that.isEmpty(properties['layText'])) layText = properties['layText'];
                item.find(':input').attr('lay-text', layText);
            },
            renderSelect: function (item) {
                initSelectOptions(item);
            },
            renderRadio: function (item) {
                initRadioOrChecxbox(item,'radio');
            },
            renderCheckbox: function (item) {
                initRadioOrChecxbox(item,'checkbox');
                var divId = item.attr('id');
                var layuiSkin=that.propertiesMap[divId]['layuiSkin'];
                if(layuiSkin=='0')item.find('[type="checkbox"]').removeAttr('lay-skin');
            },
            renderGroupLayout: function (item) {
                item.children().each(function (i, e) {
                    var itemId = 'sub_' + new Date().getTime() + '_' + i;
                    $(this).attr('id', itemId);
                    that.createSortable(itemId, {});//{draggable:'.adminj-col-item'}
                });
            },
            renderDate: function (item) {
                initDate(item,false);
            },
            renderSelect2: function (item,initParams) {
                var isInitJs=initParams['isInitJs'];
                var divId = item.attr('id');
                item.find("select").attr('id', 'select_' + divId);
                var selectedArray=[];
                initSelectOptions(item,selectedArray);
                if(isInitJs!=false){
                    item.find("select").select2().val(selectedArray);
                }
                //closeOnSelect: false
                //tags: true, tokenSeparators: [',', ' ']
            },
            renderDateRange: function (item) {
                initDate(item,true);
            },
            renderColor: function (item) {
                var divId = item.attr('id');
                var inputId = divId + '_c', colorUiId = divId + '_u';
                item.find('input').attr('id', inputId);
                item.find('[flag="color_ui_div"]').attr('id', colorUiId);
                layui.colorpicker.render({
                    elem: '#' + colorUiId
                    , color: '#1c97f5'
                    , done: function (color) {
                        $('#' + inputId).val(color);
                    }
                });
            },
            renderUploadImage: function (item) {
                var divId = item.attr('id');
                components.uploadImageFile(divId, item);
            },
            renderUploadImages: function (item) {
                var divId = item.attr('id');
                var item0 = item.find('.upload_ul').children().eq(0);
                item0.find('#close_div').children().eq(0).click(function () {
                    $(this).parent().parent().parent().remove()
                })

                components.uploadImageFile(divId, item0);
                item.find('#add_div').click(function () {
                    var node = $($('span #uploadImages .upload_ul').children(':first').get(0).outerHTML)
                    item.find('#add_div').before(node)
                    components.uploadImageFile('up_id_' + Date.now(), node)
                    var len = item.find('.upload_ul').children().length;
                    node.find('#close_div').children().eq(0).click(function () {
                        var delId = $(this).attr('del_id');
                        $(this).parent().parent().parent().remove()
                    })
                });
            },
            renderUploadFile: function (item) {
                var divId = item.attr('id');
                var fileId = divId + 'd_file';
                item.find('button').attr('id', fileId);
                layui.upload.render({
                    elem: '#' + fileId
                    , url: 'https://httpbin.org/post'
                    , accept: 'file'
                    , done: function (res) {
                        layui.layer.msg('上传成功');
                        $('#uploaded_div').html('')
                    }, progress: function (n, index, e) {
                        $('#uploaded_div').html(n + '%')
                        if (n == 100) {
                            layer.msg('上传完毕', {icon: 1});
                        }
                    }
                });
            },

            renderUploadFiles: function (item) {
                var divId = item.attr('id');
                var fileId = divId + 'u_file', uploadId = divId + 'up_file';
                item.find('[select_file="true"]').attr('id', fileId);
                item.find('[upload_file="true"]').attr('id', uploadId);
                var uploadListIns = layui.upload.render({
                    elem: '#' + fileId
                    , elemList: $('#fileList') //列表元素对象
                    , url: 'https://httpbin.org/post'
                    , accept: 'file'
                    , multiple: true
                    , number: 3
                    , auto: false
                    , bindAction: '#' + uploadId
                    , choose: function (obj) {
                        var that = this;
                        var files = this.files = obj.pushFile(); //将每次选择的文件追加到文件队列
                        //读取本地文件
                        obj.preview(function (index, file, result) {
                            var tr = $(['<tr id="upload-' + index + '">'
                                , '<td>' + file.name + '</td>'
                                , '<td>' + (file.size / 1014).toFixed(1) + 'kb</td>'
                                , '<td><div class="layui-progress" lay-filter="progress-upload-' + index + '"><div class="layui-progress-bar" lay-percent=""></div></div></td>'
                                , '<td>'
                                , '<button class="layui-btn layui-btn-xs upload-reload layui-hide">重传</button>'
                                , '<button class="layui-btn layui-btn-xs layui-btn-danger upload-delete">删除</button>'
                                , '</td>'
                                , '</tr>'].join(''));

                            //单个重传
                            tr.find('.upload-reload').on('click', function () {
                                obj.upload(index, file);
                            });

                            //删除
                            tr.find('.upload-delete').on('click', function () {
                                delete files[index]; //删除对应的文件
                                tr.remove();
                                uploadListIns.config.elem.next()[0].value = ''; //清空 input file 值，以免删除后出现同名文件不可选
                            });

                            that.elemList.append(tr);
                            layui.element.render('progress'); //渲染新加的进度条组件
                        });
                    }
                    , done: function (res, index, upload) { //成功的回调
                        var that = this;
                        //if(res.code == 0){ //上传成功
                        var tr = that.elemList.find('tr#upload-' + index)
                            , tds = tr.children();
                        tds.eq(3).html(''); //清空操作
                        delete this.files[index]; //删除文件队列已经上传成功的文件
                        return;
                        //}
                        this.error(index, upload);
                    }
                    , allDone: function (obj) { //多文件上传完毕后的状态回调
                        console.log(obj)
                    }
                    , error: function (index, upload) { //错误回调
                        var that = this;
                        var tr = that.elemList.find('tr#upload-' + index)
                            , tds = tr.children();
                        tds.eq(3).find('.upload-reload').removeClass('layui-hide'); //显示重传
                    }
                    , progress: function (n, elem, e, index) {
                        layui.element.progress('progress-upload-' + index, n + '%'); //执行进度条。n 即为返回的进度百分比
                    }
                })
            },

            renderSlider: function (item) {
                var divId = item.attr('id');
                var inputId = divId + '_slider';
                item.find('.layui-form-label').next().children().eq(0).attr('id', inputId);
                var properties=that.propertiesMap[divId];
                var min=parseInt(properties['minValue']),max=parseInt(properties['maxValue']),val=parseInt(properties['defValue']);
                var showInput=properties['showInput'];
                if (isNaN(min)) {
                    min = 0; properties['minValue']=''+min;
                }
                if (isNaN(max)) {
                    max = 100; properties['maxValue']=''+max;
                }
                if (isNaN(val)) {
                    val = 0; properties['defValue']=''+val;
                }
                if(showInput==undefined){
                    showInput='0';
                    properties['showInput']=showInput;
                }
                var isShowInput=showInput=='0'?true:false;

                layui.slider.render({
                    elem: '#' + inputId
                    , input: isShowInput
                    , value: val
                    , min: min
                    , max: max
                    , setTips: function (value) {
                        return value;
                    }
                    , change: function (val) {
                        //if(dragCallback!=undefined)dragCallback(val);
                    }
                });
            },
            renderRate: function (item) {
                var divId = item.attr('id');
                var inputId = divId + '_rate';
                var properties=that.propertiesMap[divId];
                item.find('.layui-form-label').next().children().eq(0).attr('id', inputId);
                var _value = parseInt(properties['defValue']), _rateCount = parseInt(properties['rateCount']);
                if (isNaN(_rateCount)) _rateCount = 5; properties['defValue']=_rateCount+'';
                if (isNaN(_value)) _value = 0; properties['defValue']=_value+'';
                layui.rate.render({
                    elem: '#' + inputId,
                    value: _value,
                    length: _rateCount
                })
            },
            uploadImageFile: function (divId, item) {

                var uploadButId = divId + 'd_upload';
                var filterId = 'layui-progress-' + divId;
                item.find('div[flag="upload_div"]').attr('id', uploadButId)
                item.find('.layui-progress').attr('lay-filter', filterId);
                var uploadInst = layui.upload.render({
                    elem: '#' + uploadButId
                    , url: 'https://httpbin.org/post' //改成您自己的上传接口
                    , before: function (obj) {
                        //预读本地文件示例，不支持ie8
                        var _selectLine = $('#' + uploadButId).parent().parent();
                        _selectLine.find('.bi-cloud-upload').hide();
                        _selectLine.find('#image_src').css('width', '').css('height', '').hide();
                        _selectLine.find('.upload_image_style').each(function () {
                            $(this).show();
                        });
                        _selectLine.find('#upload_bar_div').show();
                        _selectLine.find('#upload_mask_div').show();
                        obj.preview(function (index, file, result) {
                            _selectLine.find('#image_src').attr('src', result); //图片链接（base64）
                        });

                        layui.element.progress(filterId, '0%'); //进度条复位
                        //layer.msg('上传中', {icon: 16, time: 0});
                    }
                    , done: function (res) {
                        var _selectLine = $('#' + uploadButId).parent().parent();
                        _selectLine.find('#upload_bar_div').hide();
                        _selectLine.find('#upload_mask_div').hide();
                        //如果上传失败
                        if (res.code > 0) {
                            _selectLine.find('.bi-cloud-upload').show();
                            return layer.msg('上传失败');
                        }
                        //上传成功的一些操作
                        //……
                        var img = _selectLine.find('#image_src');
                        var imgWidth = img.width(), imgHeight = img.height();
                        var _imgHeight = 80 / imgHeight * imgHeight, _imgWidth = 80 / imgHeight * imgWidth;
                        img.css('width', _imgWidth + 'px').css('height', _imgHeight + 'px')
                        _selectLine.find('[update_width="true"]').each(function () {
                            $(this).css('width', _imgWidth + 'px')
                        });

                        _selectLine.find('#upload_ul').children().css('border', '0px')
                        _selectLine.find('#image_src').show();
                        _selectLine.find('.bi-cloud-upload').hide();


                        // _selectLine.find('#msgText').html(''); //置空上传失败的状态
                    }
                    , error: function () {
                        var _selectLine = $('#' + uploadButId).parent().parent();
                        //演示失败状态，并实现重传
                        _selectLine.find('#upload_bar_div').hide();
                        _selectLine.find('.upload_image_style').each(function () {
                            $(this).hide();
                        });

                    }
                    //进度条
                    , progress: function (n, index, e) {
                        layui.element.progress(filterId, n + '%'); //可配合 layui 进度条元素使用
                        if (n == 100) {
                            layer.msg('上传完毕', {icon: 1});
                        }
                    }
                });
            }, renderEditor: function (item) {//editor
                var divId = item.attr('id');
                var inputId = divId + '_editor';
                item.find('.layui-form-label').next().children().eq(0).attr('id', inputId);
                //document.querySelector('.editor')

                ClassicEditor.create(document.getElementById(inputId), {
                    toolbar: {
                        items: [
                            'heading', '|', 'bold', 'italic', 'blockQuote', 'fontColor', 'link', 'fontBackgroundColor', 'fontSize', '|', 'bulletedList', 'numberedList',
                            'outdent', 'indent', '|', 'findAndReplace', 'imageUpload', 'insertTable', 'mediaEmbed', 'CKFinder', 'undo', 'redo'
                        ]
                    },
                    language: 'zh-cn',
                    image: {
                        toolbar: ['imageTextAlternative', 'imageStyle:full', 'imageStyle:side']
                    },
                    table: {
                        contentToolbar: ['tableColumn', 'tableRow', 'mergeTableCells', 'tableCellProperties', 'tableProperties']
                    },
                    licenseKey: '',
                })
                    .then(editor => {
                        window.editor = editor;
                    })
                    .catch(error => {
                        console.error(error);
                    });


            }

        };


        return components;
    }

    AdminJLayuiFormRender.prototype.renderComponent = function (src, item, initParams, excFunc) {//执行组件的render
        var componentId = item.attr('cpt_id');
        var funcName = src + '.render' + componentId.substring(0, 1).toUpperCase() + componentId.substring(1, componentId.length);
        var func = eval(funcName);
        if (typeof (func) == 'function') {
            excFunc(func,item,initParams);
        }
    }

    
    AdminJLayuiFormRender.prototype.htmlEncode=function (s){  
                    if(s==undefined || s=='')return '';
                    s = s.replace(/&/g,"&amp;");
                    s = s.replace(/</g,"&lt;");
                    s = s.replace(/>/g,"&gt;");
                    s = s.replace(/ /g,"&nbsp;");
                    s = s.replace(/\'/g,"&#39;");
                    s = s.replace(/\"/g,"&quot;");
                    return s;  
                }
    AdminJLayuiFormRender.prototype.htmlDecode=function (s){  
          if(s==undefined || s.length == 0) return '';
          s = s.replace(/&amp;/g,"&");
          s = s.replace(/&lt;/g,"<");
          s = s.replace(/&gt;/g,">");
          s = s.replace(/&nbsp;/g," ");
          s = s.replace(/&#39;/g,"\'");
          s = s.replace(/&quot;/g,"\"");
          return s;  
    }

    AdminJLayuiFormRender.prototype.initRightPropertiesComponents = function () {//绘制右边的属性栏
        var that=this;
        var tools = {}
        tools.rootNode = undefined;
        tools.render = function (item) {
            $('#propertiesDiv').html('');
            tools.rootNode = $('#propertiesDiv');
            tools.validateRule = {
                'a_z': '字母', 'integer': '整数', 'number': '数字', 'chinese': '中文', 'a_z0_9': '英文和整数', 'username': '用户名',
                'phone': '手机号', 'email': '邮箱', 'identity': '身份证号', 'zipcode': '邮编'
            }

            var cptHtml=tools.renderRow('组件类型','<span style="font-size: 15px; font-weight: bold">'+item.attr('cpt_id')+'</span>');
            tools.rootNode.append(cptHtml);

            that.renderComponent('this.rightPropertiesComponents', item,undefined,function (func,item,initParams) {
                func(item);
            });
        }

        tools.renderBase = function (item, params) {
            var showComment = params.showComment;
            var hideName = params.hideName;

            if (!hideName) tools.renderNameInput(item, '', {nameInputFunc: params.nameInputFunc});
            tools.renderInput(item, 'Label', 'label', '', function (_obj, val) {
                item.find('.layui-form-label').html(val);
            });
            if (showComment) {
                tools.renderInput(item, '注释', 'comment', '', function (_obj, val) {
                    item.find('.layui-form-mid').html(val);
                });
            }

            tools.renderSingleCheckbox(item, '必填(选)', 'required');
            tools.renderSingleSlider(item, 'LABEL宽度', 'labelWidth', that.config.defaultLabelWidth, 300, that.config.defaultLabelWidth, 'px', function (val) {
                item.find('.layui-form-label').css('width', val + 'px');
            }, function (val) {
                item.find('.layui-form-label').css('width', val + 'px');
            });
            tools.renderSingleSlider(item, '行宽度', 'rowWidth', 30, 100, 100, '%', function (val) {
                item.css('width', val + '%');
            }, function (val) {
                item.css('width', val + '%');
            });
        }

        tools.renderNameInput = function (item, defaultVal, params) {
            var nameInputFunc = function (_obj, val) {
                var rename = item.attr('rename');//不能改名
                if (rename != 'false') {
                    item.find(':input').attr('name', val);
                }
            };
            if (params.nameInputFunc != undefined) nameInputFunc = params.nameInputFunc;
            tools.renderInput(item, '名称(name)', 'name', defaultVal, nameInputFunc);
        }


        tools.renderText = function (item) {
            tools.renderBase(item, {showComment: true});
            tools.renderInputWidth(item, {});
            tools.renderInput(item, 'placeholder', 'placeholder', '', function (_obj, val) {
                item.find('[type="text"]').attr('placeholder', val);
            });
            tools.renderInput(item, '默认值', 'defValue', '', function (_obj, val) {
                item.find('[type="text"]').val(val);
            })
            tools.renderMinMax(item);
            tools.renderLength(item);
            tools.renderValidateRegex(item);
        }

        tools.renderHidden = function (item) {
            tools.renderNameInput(item, '', {});
            tools.renderInput(item, '默认值', 'defValue', '', function (_obj, val) {
                item.find('[type="text"]').val(val);
            })
            tools.renderValidateRegex(item);
        }

        tools.renderPassword = function (item) {
            tools.renderBase(item, {showComment: true});
            tools.renderInputWidth(item, {});
            tools.renderInput(item, '默认值', 'defValue', '', function (_obj, val) {
                item.find('[type="password"]').val(val);
            });
            tools.renderLength(item);
            tools.renderValidateRegex(item);
        }

        tools.renderTextarea = function (item) {
            tools.renderBase(item, {showComment: false});
            tools.renderInputWidth(item, {initValue: 99});
            tools.renderInput(item, 'placeholder', 'placeholder', '', function (_obj, val) {
                item.find('textarea').attr('placeholder', val);
            });
            tools.renderLength(item);
            tools.renderInput(item, '默认值', 'defValue', '', function (_obj, val) {
                item.find('textarea').val(val);
            })
        }

        tools.renderDate = function (item) {
            tools.renderBase(item, {showComment: true});
            tools.renderDateFormat(item);
            tools.renderDateSelect(item, '最小日期', 'minDate');
            tools.renderDateSelect(item, '最大日期', 'maxDate');
            tools.renderSingleCheckbox(item, '当前时间为初始值', 'currentTime');
            tools.renderSingleCheckbox(item, '提交时格式化为毫秒', 'milliscondFormat')
        }

        tools.renderGroupLayout = function (item) {
            var divId = item.attr('id');

            var countChildFunc = function (obj) {//且计算子一级有 .adminj-col-item 的item数量
                var count = 0
                obj.children().each(function () {
                    if ($(this).hasClass('adminj-col-item')) {
                        count++;
                    }
                });
                return count;
            };

            var initLayoutEvent = function (item) {//递归重置事件
                that.createSortableItemUI(item);
                item.find('.adminj-col-item').children().each(function (i, e) {
                    initLayoutEvent($(this));
                });
            };


            var currentGroupCount = that.propertiesMap[divId]['groupCount'];
            if (currentGroupCount == undefined) {
                currentGroupCount = countChildFunc(item);
                that.propertiesMap[divId]['groupCount'] = currentGroupCount + '';
            } else {
                currentGroupCount = parseInt(currentGroupCount);
            }

            var _html = '<select  lay-ignore name="groupCount" id="groupCount" style="height: 30px; width:150px;">' +
                '<option value="1">1</option>' +
                '<option value="2">2</option>' +
                '<option value="3">3</option>' +
                '<option value="4">4</option>' +
                '</select>';
            _html = tools.renderRow('例数量', _html);
            var html=$(_html);
            tools.rootNode.append(html);
            var select=html.find('select');
            select.val(currentGroupCount);

            var divId = item.attr('id');
            select.change(function () {
                var val = parseInt($(this).val());
                var count = countChildFunc(item);
                if (count == val) return;
                var col = 12 / val;

                if (val < count) {//删除多的项目
                    var index = 0;
                    var srcHtml = $(item.get(0).outerHTML);//需要COPY整个节点，再重置事件，不然拖动时乱跳
                    srcHtml.children().each(function (i, e) {
                        if ($(this).hasClass('adminj-col-item')) {
                            if (index >= val) {
                                $(this).remove();
                            } else {
                                $(this).removeAttr('class').addClass('group-layout-border adminj-col-item layui-col-md' + col);
                            }
                            index++;
                        }
                    });
                    that.propertiesMap[divId]['groupCount'] = val + '';
                    item.after(srcHtml);
                    item.remove();
                    item=srcHtml;
                    initLayoutEvent(srcHtml);

                    return;
                }

                var loop = val - count;
                var _itemHtml = '';
                var index = val + 1;
                for (var i = 0; i < loop; i++) {
                    var itemId = 'sub_' + new Date().getTime() + '_' + index;
                    _itemHtml += '    <div class="group-layout-border adminj-col-item "  id="' + itemId + '"  ></div>\n';
                    index++;
                }
                var itemHtml = $(_itemHtml);
                item.append(itemHtml);

                index = 0;
                item.children().each(function (i, e) {
                    if ($(this).hasClass('adminj-col-item')) {
                        $(this).removeAttr('class').addClass('group-layout-border adminj-col-item layui-col-md' + col);
                        if (index >= count) {
                            var itemId = $(this).attr('id');
                            that.createSortable(itemId, {});//{draggable: '.adminj-col-item'}
                        }
                        index++;
                    }
                });
                that.propertiesMap[divId]['groupCount'] = val + '';

            });


        }

        tools.renderSwitch = function (item) {
            tools.renderBase(item, {showComment: true});
            tools.renderInput(item, '显示文本', 'layText', 'NO|OFF', function (_obj, val) {
                item.find(':input').attr('lay-text', val);
                layui.form.render('checkbox');
            })
            var properties = that.propertiesMap[item.attr('id')];
            properties['isSelect']='0';
            properties['selectedValue']='0';
            properties['defValue']='1';
            tools.renderSingleCheckbox(item,'选中','isSelect',function (data, val) {
                var properties = that.propertiesMap[item.attr('id')];
                if(val=='0'){
                    item.find('input').prop('checked','checked');
                }else{
                    item.find('input').removeAttr('checked');
                }
                properties['isSelect']=val;
                layui.form.render('checkbox');
            });
            tools.renderInput(item, '选中值', 'selectedValue','0')
            tools.renderInput(item, '未选中值', 'defValue','1')
        }

        tools.renderSelect2 = function (item) {
            tools.renderBase(item, {showComment: false});
            tools.renderInputWidth(item, {});

            tools.renderMultiKeyValue(item);
        }

        tools.renderSelect = function (item) {
            tools.renderBase(item, {showComment: true});
            tools.renderMultiKeyValue(item);
        }


        tools.renderMultiKeyValue = function (item) {
            var cptId = item.attr('cpt_id');
            var divId = item.attr('id');
            var inputType = 'radio';
            if (cptId == 'checkbox' || cptId == 'select2') {
                inputType = 'checkbox';
            }
            var properties=that.propertiesMap[divId];
            var options = properties['options'];
            if (options == undefined) {
                options = [{value: '0', text: '选择', isSelect: '0'},
                    {value: '1', text: '选项2', isSelect: '1'}, {value: '2', text: '选项3', isSelect: '1'}];
                properties['options'] = options;
            }

            var proItemFunc = function (i, cptId, inputType, optionItem) {//select的item
                var selected = optionItem.isSelect == '0' ? 'checked' : '';
                var propertiesHtml = '', uiHtml = '';
                propertiesHtml += '    <tr index="' + i + '">\n' +
                    '    <td><input type="' + inputType + '" name="isSelect"  lay-skin="primary" lay-filter="isSelect" value="' + optionItem.value + '" ' + selected + '></td>\n' +
                    '    <td style="padding-top: 3px;"><input type="text" name="value" value="' + optionItem.value + '" class="layui-input"></td>\n' +
                    '    <td style="padding-left: 3px;padding-top: 3px;"><input type="text" name="text" value="' + optionItem.text + '" class="layui-input"></td>\n' +
                    '    <td align="center"><i class="layui-icon layui-icon-close-fill" style="font-size: 2em;color: #c7ced5"></i></td>\n' +
                    '  </tr>\n';
                if (cptId == 'select' || cptId == 'select2') {
                    selected = optionItem.isSelect == '0' ? 'selected' : '';
                    uiHtml += '<option value="' + optionItem.value + '" index="' + i + '" ' + selected + '>' + optionItem.text + '</option>';
                } else if (cptId == 'radio' || cptId == 'checkbox') {
                    selected = optionItem.isSelect == '0' ? 'checked' : '';
                    var skin='',layuiSkin=properties['layuiSkin'];
                    if(layuiSkin!='0')skin='lay-skin="primary"';
                    uiHtml += '<input name="" type="' + inputType + '" '+skin+' value="' + optionItem.value + '" index="' + i + '" ' + selected + ' title="' + optionItem.text + '">';
                }

                return {propertiesHtml, uiHtml};//右边工具栏的HTML，中间的编辑HTML
            };

            var uiHtml = '';
            var _html = '<br><br>' +
                '<button class="layui-btn layui-btn-primary layui-border-blue layui-btn-sm" id="new_line_butt">' +
                '<i class="layui-icon layui-icon-add-circle-fine" style="font-size: 16px;"></i> 添加新项</button>' +
                '<table width="100%" border="0" style="margin-top: 5px;" id="option_table" count="' + options.length + '">\n';

            for (var i = 0; i < options.length; i++) {
                if (options[i] == undefined) continue;
                var resArr = proItemFunc(i, cptId, inputType, options[i]);
                _html += resArr.propertiesHtml;
                uiHtml += resArr.uiHtml;
            }

            _html += '</table>';

            var html = $(_html);

            var queryIndex = function (trIndex) {//得到当前tr在数组的index
                var index = 0;
                html.find('.layui-icon-close-fill').parent().parent().each(function (i, e) {
                    var _index = $(this).attr('index');
                    if (_index == trIndex) {
                        index = i;
                        return false;
                    }
                });
                return index;
            };
            var clickEventFunc = function (item, cptId, html) {
                //var divId=obj.attr('id');
                html.find('.layui-icon-close-fill').each(function (i, e) {
                    $(this).click(function () {//delete
                        var index = $(this).parent().parent().attr('index');
                        var arrayIndex = queryIndex(index);
                        options.splice(arrayIndex, 1);//删除数据
                        if (cptId == 'select' || cptId == 'select2') {
                            item.find('select option[index=' + index + ']').remove();
                        } else {
                            var index = $(this).parent().parent().attr('index');
                            var findRes = item.find('[index=' + index + ']');
                            findRes.next().remove();
                            findRes.remove();
                        }
                        $(this).parent().parent().remove();
                        layui.form.render();
                    });
                });

                html.find('[name="value"]').each(function (i, e) {
                    $(this).focusout(function () {
                        var index = $(this).parent().parent().attr('index');
                        var val = $(this).val();
                        var jqueryFindName = 'select option[index=' + index + ']';//select select2
                        if (cptId == 'radio' || cptId == 'checkbox') {
                            jqueryFindName = '[index=' + index + ']';
                        }
                        var findRes = item.find(jqueryFindName);
                        findRes.attr('value', val);
                        if(cptId == 'select2'){
                                item.find('select').trigger('destroy').select2();
                        }
                        var arrayIndex = queryIndex(index);
                        options[arrayIndex]['value'] = val;//修改value
                        layui.form.render();
                    });
                });

                html.find('[name="text"]').each(function (i, e) {
                    $(this).focusout(function () {
                        var index = $(this).parent().parent().attr('index');
                        var val = $(this).val();
                        var _val=that.htmlEncode(val);
                        var jqueryFindName = 'select option[index=' + index + ']';//select select2
                        if (cptId == 'radio' || cptId == 'checkbox') {
                            jqueryFindName = '[index=' + index + ']';
                        }
                        var findRes = item.find(jqueryFindName);
                        if (cptId == 'select' || cptId == 'select2') {
                            findRes.text(val);
                            if(cptId == 'select2'){
                                item.find('select').trigger('destroy').select2();
                            }
                        } else {
                            findRes.attr('title', _val);
                        }

                        var arrayIndex = queryIndex(index);
                        options[arrayIndex]['text'] = _val;//修改text
                        layui.form.render();
                    });
                });


            }

            var checkboxSelect = function (item) {//设置select的选中值
                var arr = [], index = 0;
                $('[name="isSelect"]').each(function (i, e) {
                    if ($(this).is(':checked')) {
                        arr[index] = $(this).val();
                        index++;
                    }
                });
                item.find('select').val(arr).trigger('change');
            }

            clickEventFunc(item, cptId, html);

            layui.form.on('radio(isSelect)', function (data) {//option属性前如里是radio
                
                for (var i = 0; i < options.length; i++) {
                    options[i]['isSelect'] = options[i]['value'] == data.value ? '0' : '1';
                }
                if (cptId == 'radio') {
                    //var index = $(data.elem).parent().parent().attr('index');
                    //item.find('[index=' + index + ']').prop('checked', 'true');
                    item.find('[type="radio"]').each(function(i,e){
                       if( $(this).val()==data.value){
                        $(this).prop('checked', 'true');
                       }else{
                        $(this).prop('checked', '');
                       }
                    })
                } else {
                    item.find(':input').val(data.value);
                }

                layui.form.render();
            });
            layui.form.on('checkbox(isSelect)', function (data) {//option属性前如里是checkbox
                if (cptId == 'checkbox') {
                    item.find('[type="checkbox"]').each(function(i,e){
                       if( $(this).val()==data.value){
                            if (data.elem.checked) {
                                $(this).prop('checked', 'true');
                            }else{
                                $(this).prop('checked', '');
                            }
                            return;
                        }
                    });
                    // var index = $(data.elem).parent().parent().attr('index');

                    layui.form.render();
                } else {
                    checkboxSelect(item);
                }

                var selected = data.elem.checked ? '0' : '1';
                var index = $(data.elem).parent().parent().attr('index');
                var arrayIndex = queryIndex(index);
                options[arrayIndex]['isSelect'] = selected;
            });

            tools.rootNode.append(html);
            $('#new_line_butt').click(function (data) {

                var count = parseInt($('#option_table').attr('count'));
                count++;
                var arrItem = {value: count, text: '选项' + count, isSelect: '1'};
                var resArr = proItemFunc(count, cptId, inputType, arrItem);
                var html = $(resArr.propertiesHtml);
                options[options.length] = arrItem;

                clickEventFunc(item, cptId, html);
                $('#option_table').append(html);
                $('#option_table').attr('count', count);

                if (cptId == 'select' || cptId == 'select2') {
                    item.find('select').append(resArr.uiHtml);
                } else {
                    item.find('label').next().append(resArr.uiHtml);
                    //obj.find(':input').parent().append(resArr[1]);
                }

                layui.form.render();

                return false;
            });

            if (cptId == 'select' || cptId == 'select2') {
                item.find('select').html(uiHtml);
            } else {
                item.find(':input').parent().html(uiHtml);
            }

            //var newOption = new Option('data.text', 'data.id', true, true);
            // $('#'+id).append(newOption).trigger('change');

            if (cptId == 'select') {
                for (var i = 0; i < options.length; i++) {
                    if (options[i]['isSelect'] == '0') {
                        item.find('select').val(options[i]['value']);
                        layui.form.render();
                        break;
                    }
                }

            } else if (cptId == 'select2') {
                checkboxSelect(item);
            }


            layui.form.render();
        }

        tools.renderRadio = function (item) {
            tools.renderBase(item, {showComment: true});
            tools.renderInputWidth(item, {});
            tools.renderMultiKeyValue(item);
        }

        tools.renderCheckbox = function (item) {
            tools.renderBase(item, {showComment: true});
            tools.renderInputWidth(item, {});
            tools.renderSingleCheckbox(item, 'layui样式', 'layuiSkin',function (data,val) {
                if(val=='1'){
                    item.find('[type="checkbox"]').attr('lay-skin','primary');
                }else{
                    item.find('[type="checkbox"]').removeAttr('lay-skin');
                }
                layui.form.render('checkbox');
            });
            tools.renderMultiKeyValue(item);
        }


        tools.renderColor = function (item) {
            tools.renderBase(item, {showComment: false});
            tools.renderInput(item, 'placeholder', 'placeholder', '', function (_obj, val) {
                item.find('[type="text"]').attr('placeholder', val);
            });
            tools.renderInput(item, '默认值', 'defValue', '', function (_obj, val) {
                item.find('[type="text"]').val(val);
            })
        }

        tools.renderUploadImage = function (item) {
            tools.renderBase(item, {});
            tools.renderInput(item, '上传地址', 'uploadUrl')
            tools.renderUploadConfig(item, ['.jpg', '.gif', '.png'])

        }

        tools.renderUploadImages = function (item) {
            tools.renderBase(item, {});
            tools.renderSingleSlider(item, '上传区宽度', 'inputWidth', 50, 99, 80, '%', function (val) {
                item.find('.layui-form-label').next().css('width', val + '%');
            }, function (val) {
                item.find('.layui-form-label').next().css('width', val + '%');
            });
            tools.renderInput(item, '上传地址', 'uploadUrl')
            tools.renderUploadCount(item)
            tools.renderUploadConfig(item, ['.jpg', '.gif', '.png'])
        }

        tools.renderUploadFile = function (item) {
            tools.renderBase(item, {});
            tools.renderSingleSlider(item, 'LABEL宽度', 'labelWidth', that.config.defaultLabelWidth, 300, that.config.defaultLabelWidth, 'px', function (val) {
                item.find('.layui-form-label').css('width', val + 'px');
            }, function (val) {
                item.find('.layui-form-label').css('width', val + 'px');
            });
            tools.renderInput(item, '上传地址', 'uploadUrl')
            tools.renderUploadSize(item)
            tools.renderInputSelect2( item,'上传格式(:输入 .jpg 后回车)', 'uploadType',  '输入上传格式后回车,格式前带上.')
        }

        tools.renderUploadFiles = function (item) {
            tools.renderBase(item, {});
            tools.renderSingleSlider(item, 'LABEL宽度', 'labelWidth', that.config.defaultLabelWidth, 300, that.config.defaultLabelWidth, 'px', function (val) {
                item.find('.layui-form-label').css('width', val + 'px');
            }, function (val) {
                item.find('.layui-form-label').css('width', val + 'px');
            });
            tools.renderInput(item, '上传地址', 'uploadUrl')
            tools.renderUploadCount(item)
            tools.renderUploadSize(item)
            tools.renderInputSelect2( item,'上传格式(:输入 .jpg 后回车)', 'uploadType', '输入上传格式后回车,格式前带上.')
        }


        tools.renderSlider = function (item) {
            tools.renderBase(item, {showComment: true});
            tools.renderInputWidth(item, {});

            var properties = that.propertiesMap[item.attr('id')]
            //properties['showInput'] = '0';//初始值

            var sliderFunc = function (params) {
                var showInput = params.showInput;
                var min = parseInt($('#minValue').val()), max = parseInt($('#maxValue').val()),
                    val = parseInt($('#defValue').val());
                var suffix = $('#suffix').val();
                if (showInput == undefined) showInput = true;
                if (isNaN(min)) min = 0;
                if (isNaN(max)) max = 100;
                if (isNaN(val)) val = 0;

                var inputId = item.attr('id') + '_slider';
                item.find('.layui-form-label').next().children().eq(0).attr('id', inputId);
                layui.slider.render({
                    elem: '#' + inputId
                    , input: showInput
                    , value: val
                    , min: min
                    , max: max
                    , setTips: function (value) {
                        return value + suffix;
                    }
                });

            }

            var min=properties['minValue'],max=properties['maxValue'],val=properties['defValue'];
            var suffix=properties['suffix'];

            tools.renderSingleCheckbox(item, '显示输入框', 'showInput', function (data, val) {
                sliderFunc({showInput: data.elem.checked});
            });
            tools.renderInput(item, '拖动时显示的后缀', 'suffix', suffix, function (_obj, val) {
                sliderFunc({});
            })
            tools.renderInput(item, '默认值', 'defValue', val, function (_obj, val) {
                sliderFunc({});
            })
            tools.renderInput(item, '最小值', 'minValue', min, function (_obj, val) {
                sliderFunc({});
            })
            tools.renderInput(item, '最大值', 'maxValue', max, function (_obj, val) {
                sliderFunc({});
            })
        }

        tools.renderRate = function (item) {
            var inputId = item.attr('id') + '_rate';
            tools.renderBase(item, {showComment: true});
            tools.renderInputWidth(item, {});

            var rateFunc = function () {
                var _value = parseInt($('#defValue').val()), _rateCount = parseInt($('#rateCount').val());
                if (isNaN(_rateCount)) _rateCount = 5;
                if (isNaN(_value)) _value = 0;
                layui.rate.render({
                    elem: '#' + inputId,
                    value: _value,
                    length: _rateCount
                })
            }

            var properties = that.propertiesMap[item.attr('id')];
            var _value = properties['defValue'], _rateCount = properties['rateCount'];
            if(_rateCount=='' || _rateCount==undefined)_rateCount='5';
            tools.renderInput(item, '默认值', 'defValue', _value, function (_obj, val) {
                rateFunc();
            })
            tools.renderInput(item, '星星数量', 'rateCount', _rateCount, function (_obj, val) {
                rateFunc();
            })


        }


        tools.renderEditor = function (item) {
            tools.renderBase(item, {showComment: true});
            tools.renderInputWidth(item, {initWidth: 88});

            tools.renderLength(item);

        }

        tools.initDataSelectEvent = function (item,html,isRange){
            var select=html.find('select');

            var dataId='dateFormat';
            var properties = that.propertiesMap[item.attr('id')]
            if (properties[dataId] != undefined) {
                var selectVal = properties[dataId].split('|')[1]
                select.val(selectVal)
            } else {
                properties[dataId] = 'date' + '|' + 'yyyy-MM-dd'
            }

            select.change(function () {
                var dateDivId = item.find('input').attr('id');

                var selectDiv = item.find('#' + dateDivId).parent();
                var html = selectDiv.html();
                selectDiv.children().remove();
                selectDiv.html(html);

                var selectUI = $(this).find('option[value="' + $(this).val() + '"]').attr('ui');
                var _timeUI = layui.laydate.render({
                    elem: '#' + dateDivId
                    , type: selectUI
                    , range: isRange
                    , change: function (value, date) {

                    }
                    , done: function (value, date) {
                        console.log(value)
                    }
                });

                properties[dataId] = selectUI + '|' + $(this).val()

            })
        }

        tools.renderSelectS = function (item) {
            
            var divId=item.attr('id');
            tools.renderBase(item, {showComment: true});
            tools.renderInput(item, 'ajax url', 'requestURL', '');
            var html=tools.renderRow('选择提示(一行一个)','<textarea id="defOptions" style="width:98%;height:100px;"></textarea>');
            tools.rootNode.append(html);

            var options=that.propertiesMap[divId]['defOptions'];
            var _options='';
            if(options!=undefined){
                for(var i=0;i<options.length;i++){
                    _options+=options[i]+'\n';
                }
            }
            $('#defOptions').val(_options);

            
            $('#defOptions').focusout(function(){
                var arr=$(this).val().split('\n'),newArr=[];
                for(var i=0;i<arr.length;i++){
                    if(arr[i]!='')newArr[newArr.length]=arr[i];
                }
                that.propertiesMap[divId]['defOptions']=newArr;
            });

            var selectFunc=function(url,parentId){
                var newUrl=url+'parentId='+parentId;

                    ajaxData('get',newUrl,{},function(res){
                    var list=res[that.config.ajaxRequestName.resultName];
                    //var v='{"resultCode":0,"result":[{"isSelect":"1","text":"title0","value":"0"},{"isSelect":"1","text":"title1","value":"1"},{"isSelect":"1","text":"title2","value":"2"},{"isSelect":"1","text":"title3","value":"3"}]}';
                    //list=JSON.parse(v);
                    //list=list.result;

                    if(list!=undefined && list.length>0){
                        var options=that.propertiesMap[divId]['defOptions'];
                        var defText='选择';
                        var len=item.find('select').length;
                        if(options!=undefined && options.length>len)defText=options[len];
                        var selectId='selects_id_'+len;
                        var _html='<div class="layui-input-inline"><select id="'+selectId+'" lay-filter="'+selectId+'">';
                            _html+='<option value="">'+defText+'</option>';
                        for(var i=0;i<list.length;i++){
                            var row=list[i];
                            _html+='<option value='+row.value+'>'+row.text+'</option>';
                        }
                        _html+='</select></div>';
                        var html=$(_html);
                        item.find('.layui-form-mid').before(html);

                        layui.form.on('select('+selectId+')', function(data){
                            var selectId=$(data.elem).attr('id');
                            $('#'+selectId).parent().nextAll().each(function(i,e){
                                if($(this).attr('class').indexOf('layui-input-inline')!=-1){
                                    $(this).remove();
                                }
                            });
                            selectFunc(url,data.value);
                        });
                        
                    }
                    
                    layui.form.render('select');
                },that.config.ajaxRequestName);
            }

            $('#requestURL').focusout(function(){
                var url=$(this).val();
                if(that.isEmpty(url))return false;
                url=url+(url.indexOf('?')==-1)?'?':'&';
                selectFunc(url,'');
            });
        }

        tools.renderDateRange = function (item) {
            tools.renderInput(item, '开始时间Name', 'startDateName', '');
            tools.renderInput(item, '结束时间Name', 'endDateName', '');
            tools.renderBase(item, {hideName: true, showComment: true})
            tools.renderDateSelect(item, '最小日期', 'minDate');
            tools.renderDateSelect(item, '最大日期', 'maxDate');
            tools.renderSingleCheckbox(item, '当前时间为初始值', 'currentTime');
            tools.renderSingleCheckbox(item, '提交时格式化为毫秒', 'milliscondFormat')

            var rangeOptions=[{value:'yyyy-MM-dd',ui:'date',text:'yyyy-MM-dd'},
                {value:'yyyy',ui:'year',text:'yyyy'},
                {value:'MM',ui:'month',text:'MM'},
                {value:'HH:mm',ui:'time',text:'HH:mm'},
                {value:'yyyy-MM-dd HH:mm:ss',ui:'datetime',text:'yyyy-MM-dd HH:mm:ss'},];

            var _html = '<select lay-ignore name="dateFormat" id="dateFormat" style="height: 30px;width:60%">';
            for (var i = 0; i < rangeOptions.length; i++) {
                var row=rangeOptions[i];
                _html += '<option value="'+row.value+'" ui="'+row.ui+'">'+row.text+'</option>';
            }
            _html += '</select>';
            _html = tools.renderRow('日期格式', _html);
            var html = $(_html);
            tools.rootNode.append(html);
            tools.initDataSelectEvent(item, html, true);


        }

        tools.renderDateSelect = function (item, label, _id) {
            var _html = '<input type="text" id="' + _id + '" class="layui-input" >';
            _html = tools.renderRow(label, _html);
            var html = $(html);
            tools.rootNode.append(html);

            var properties = that.propertiesMap[item.attr('id')]
            var val = (properties[_id] != undefined) ? properties[_id] : '';

            html.find(":input").attr('id', _id);
            layui.laydate.render({
                elem: '#' + _id,
                value: val
                , done: function (value, date, endDate) {
                    properties[_id] = value;
                }
            });


        }

        tools.renderDateFormat = function (item) {
            var rangeOptions = [{value: 'yyyy-MM-dd', ui: 'date', text: 'yyyy-MM-dd'},
                {value: 'yyyy-MM', ui: 'month', text: 'yyyy-MM'},
                {value: 'yyyy', ui: 'year', text: 'yyyy'},
                {value: 'MM-dd', ui: 'date', text: 'MM-dd'},
                {value: 'MM', ui: 'month', text: 'MM'},
                {value: 'dd', ui: 'date', text: 'dd'},
                {value: 'HH:mm', ui: 'time', text: 'HH:mm'},
                {value: 'yyyy-MM-dd HH:mm:ss', ui: 'datetime', text: 'yyyy-MM-dd HH:mm:ss'},
                {value: 'MM-dd HH:mm', ui: 'datetime', text: 'MM-dd HH:mm'},];

            var _html = '<select lay-ignore name="dateFormat" id="dateFormat" style="height: 30px;">' ;
            for (var i = 0; i < rangeOptions.length; i++) {
                var row = rangeOptions[i];
                _html += '<option value="' + row.value + '" ui="' + row.ui + '">' + row.text + '</option>';
            }
            _html += '</select>';
            _html = tools.renderRow('日期格式', _html);
            var html = $(_html);
            tools.rootNode.append(html);

            tools.initDataSelectEvent(item, html, false);
        }

        tools.renderMinMax = function (item) {
            tools.renderInput(item, '最小值', 'minValue')
            tools.renderInput(item, '最大值', 'maxValue')
        }
        tools.renderLength = function (item) {
            tools.renderInput(item, '内容最小长度', 'minLength')
            tools.renderInput(item, '内容最大长度', 'maxLength')
        }


        tools.renderUploadConfig = function (item, uploadType) {
            tools.renderUploadSize(item);
            tools.renderUploadType(item, uploadType);
        }

        tools.renderUploadSize = function (item) {
            tools.renderInput(item, '单文件最小(KB)', 'minSize')
            tools.renderInput(item, '单文件最大(KB)', 'maxSize')
        }

        tools.renderUploadType = function (item, uploadType) {

            var _html = '<select lay-ignore id="uploadType" class="select2" multiple="multiple" data-placeholder="" data-dropdown-css-class="select2-purple" style="width: 100%;">\n';
            for (k in uploadType) {
                _html += '<option value="' + uploadType[k] + '">' + uploadType[k] + '</option>\n';
            }

            _html += '</select>';
            _html = tools.renderRow('上传格式', _html);
            var html=$(_html);
            tools.rootNode.append(html);

            var select=html.find('select');

            select.select2({
                closeOnSelect: false
            });
            tools.select2Event(item, select)

        }

        tools.select2Event = function (item, select) {
            var id=select.attr('id');
            var properties = that.propertiesMap[item.attr('id')]
            if (properties[id] != undefined) {
                select.val(properties[id]);
                select.trigger('change');
            }else{
                properties[id] = [];
            }

            select.on('select2:select', function (e) {
                var arr = properties[id]
                arr[arr.length] = e.params.data.id;
            }).on('select2:unselect', function (e) {
                var text = e.params.data.id;
                var arr = properties[id]
                for (i = 0; i < arr.length; i++) {
                    if (arr[i] == text) {
                        arr.splice(i, 1);
                        break;
                    }
                }
            });
        }


        tools.renderUploadCount = function (item) {
            tools.renderInput(item, '上传最大个数', 'uploadCount');

        }

        tools.renderInput = function (item, label, _id, defaultVal, inputCallback) {
            if (defaultVal == undefined) defaultVal = ''

            var _html = '<input type="text" id="' + _id + '"  class="layui-input"  value="' + defaultVal + '" >';
            _html = tools.renderRow(label, _html);
            var html=$(_html);
            tools.rootNode.append(html);
            var input=html.find('input');

            var properties = that.propertiesMap[item.attr('id')]
            if (properties[_id] != undefined) input.val(properties[_id])
            //$('#'+_id).unbind("change");
            input.keyup(function () {
                var val = $(this).val();
                properties[$(this).attr('id')] = that.htmlEncode(val);
                if (inputCallback != undefined) inputCallback($(this), val);
            })

        }


        tools.renderSingleCheckbox = function (item, label, _id, clickCallback) {
            var properties = that.propertiesMap[item.attr('id')]
            var check = properties[_id] == '0' ? 'checked' : '';

            var html = '<ul class="propertiesdiv_sp">\n' +
                '                        <li style="margin-top: 15px; margin-bottom: 15px;">\n' +
                '                            <input type="checkbox" name="' + _id + '" id="' + _id + '" lay-skin="primary" title="' + label + '" lay-filter="' + _id + '" ' + check + '>\n' +
                '                        </li>\n' +
                '                    </ul>';
            //milliscondFormat
            tools.rootNode.append(html);

            layui.form.on('checkbox(' + _id + ')', function (data) {
                var val = data.elem.checked ? '0' : '1';
                properties[$(this).attr('id')] = data.elem.checked ? '0' : '1';
                if (clickCallback != undefined) clickCallback(data, val);
            });

            layui.form.render('checkbox');

        }

        //appendInputWidth,30,100,intval=60
        tools.renderInputWidth = function (item, params) {
            var initWidth = params.initWidth == undefined ? 60 : params.initWidth;
            tools.renderSingleSlider(item, '输入框宽度', 'inputWidth', 30, 99, initWidth, '%', function (val) {
                item.find('.layui-form-label').next().css('width', val + '%');
            }, function (val) {
                item.find('.layui-form-label').next().css('width', val + '%');
            });
        }

        tools.renderSingleSlider = function (obj, label, _id, min, max, initValue, valueEnd, dragCallback, initCallback) {
            var html = '<ul class="propertiesdiv_sp"><li style="margin-top: 10px;margin-bottom: 8px;">' + label + '</li>\n' +
                '      <li><div id="' + _id + '" ></div></li></ul>';
            tools.rootNode.append(html);

            var initVal = initValue;
            var properties = that.propertiesMap[obj.attr('id')]
            if (properties[_id] == undefined) {
                properties[_id] = initVal + '';
            } else {
                initVal = properties[_id];
            }
            if (initCallback != undefined) initCallback(initVal);
            layui.slider.render({
                elem: '#' + _id
                , input: true
                , value: initVal
                , min: min
                , max: max
                , setTips: function (value) {
                    return value + valueEnd;
                }
                , change: function (val) {
                    properties[_id] = val + '';
                    if (dragCallback != undefined) dragCallback(val);
                }
            });

        }

        tools.renderValidateRegex = function (item) {
            var _html = '<select lay-ignore id="validateRule" class="select2" multiple="multiple" data-placeholder="" data-dropdown-css-class="select2-purple" style="width: 100%;">\n';
            for (k in tools.validateRule) {
                var name = tools.validateRule[k];
                _html += '<option value="' + k + '">' + name + '</option>\n';
            }

            _html += '</select>';
            _html = tools.renderRow('验证规则', _html);
            var html=$(_html);
            tools.rootNode.append(html);
            var select=html.find('select');
            select.select2();

            tools.select2Event(item, select)

        }

        tools.renderInputSelect2 = function (item,label, id,  help) {
            var divId=item.attr('id');
            var _html = '<select lay-ignore id="' + id + '" class="select2" multiple="multiple" data-placeholder="' + help + '" data-dropdown-css-class="select2-purple" style="width: 100%;">\n';
            var arr=that.propertiesMap[divId][id];
            for (index in arr) {
                var val = arr[index];
                _html += '<option value="' + val + '">' + val + '</option>\n';
            }
            _html += '</select>';
            _html = tools.renderRow(label, _html);
            var html=$(_html);
            tools.rootNode.append(html);
            var select=html.find('select');
            select.select2({
                tags: true
            });

            tools.select2Event(item, select)

        }

        tools.renderRow = function (label, input) {
            var html = '<ul class="propertiesdiv_sp"><li style="margin-top: 0px;">' + label + '</li>\n<li>' + input + '</li></ul>';
            return html;
        }


        return tools;
    }


    AdminJLayuiFormRender.prototype.exportSingleItemJSON = function (i, item, resArr) {//导出单条ITEM结构为JSON
        var that=this;
        var cptId = item.attr('cpt_id'), id = item.attr('id');
        if (cptId == 'groupLayout') {
            var _arrL1 = {id:cptId,children:[]};
            resArr[resArr.length] = _arrL1;
            item.children().each(function (j, e) {
                if(!$(this).hasClass('action-tools')) {
                    var children = [];
                    _arrL1.children[j] = children;
                    $(this).children().each(function (k, e) {
                        var child = $(this);
                        that.exportSingleItemJSON(k, child, children);
                    });
                }
            });
        } else {
            var pro=that.propertiesMap[id];
            if(pro!=undefined) {
                resArr[resArr.length] = pro;
            }
        }
    }

    AdminJLayuiFormRender.prototype.exportJSON = function () {//导出结构为JSON
        var that=this;
        var arr = [];

        $('#sortable').children().each(function (i, e) {
            var item = $(this);
            that.exportSingleItemJSON(i, item, arr);
        });

        var str = JSON.stringify(arr);
        return str;

    }

    AdminJLayuiFormRender.prototype.createItemBySingleData = function (parentNode, rowData, params) {//从JSON DATA生成单个的ITEM
        var that=this;
        var copyNode=params.copyNode;//如果的COPY的则传被COPY的节点
        var _divId=params.divId;
        var cptId = rowData.id;
        var divId =params.index==0 && _divId!=undefined?_divId: 'did_' + Date.now() + "_" + params.index;

        var html = $($('#cpts_items').find("#" + cptId).get(0).outerHTML);
        html.attr('id', divId).attr('cpt_id', cptId);
        that.propertiesMap[divId] = rowData;
        if(copyNode!=undefined && params.index==0){//如果是copy的则放到copy节点的后面
            copyNode.after(html);
        }else{
            parentNode.append(html);
        }

        params.index++;

        if (cptId != 'groupLayout') {
            that.createSortableItemUI(html);
            return ;
        }

        var subItemHtml = $('#cpts_items').find("#" + cptId).children().get(0).outerHTML;
        html.html('');
        var children = rowData.children;
        if(children!=undefined) {
            for (var i = 0; i < children.length; i++) {
                var itemHtml = $(subItemHtml);
                var sortItemId = 'sub_' + new Date().getTime() + '_' + i;
                itemHtml.attr('id', sortItemId);
                itemHtml.removeAttr('class').addClass('group-layout-border adminj-col-item layui-col-md' + (12 / rowData.children.length));
                html.append(itemHtml);
                var _arrL1 = children[i];
                for (var j = 0; j < _arrL1.length; j++) {
                    var _arrL2 = _arrL1[j];
                    that.createItemBySingleData(itemHtml, _arrL2, params);
                }
            }
        }
        that.createSortableItemUI(html);
        delete rowData['children'];//子节点无用数据删除
    }

    AdminJLayuiFormRender.prototype.importJSON = function (str) {//导入json生成form
        var that=this;
        if (str.length < 2) return;
        var json = undefined;
        try {
            json = JSON.parse(str);
        } catch (e) {
            layui.layer.msg(e);
            return;
        }
        that.propertiesMap = {};
        $('#sortable').html('');
        $('#propertiesDiv').html('');


        var params={index:0};
        var parentNode=$('#sortable');
        for (var i = 0; i < json.length; i++) {
            var row = json[i];
            that.createItemBySingleData(parentNode,row,params);
        }

        layui.form.render();



    }

    AdminJLayuiFormRender.prototype.exportToHTML = function () {
        var that=this;
        var createValidateFunc=function (rowData,item){//生成验证代码
            var isReq=rowData['required'];
            var rule=rowData['validateRule'];
            var validateStr='';
            if(rule!=undefined){
                for(var i=0;i<rule.length;i++){
                    validateStr+=rule[i];
                    if(i<rule.length-1)validateStr+='|';
                }
            }

            var appendValidateRuleFunc = function (validateName) {
                validateStr += validateStr.length > 0 ? '|' : '';
                validateStr += validateName;
            }

            var appendIntValidateRuleFunc = function (validateName, dataKey) {
                var val = parseInt(rowData[dataKey]);
                if (!isNaN(val)) {
                    appendValidateRuleFunc(validateName);
                }
            }

            appendIntValidateRuleFunc('minLength', 'minLength');
            appendIntValidateRuleFunc('maxLength', 'maxLength');
            appendIntValidateRuleFunc('min', 'minValue');
            appendIntValidateRuleFunc('max', 'maxValue');

            if(isReq=='0'){
                appendValidateRuleFunc('required');
            }
            if(validateStr.length>0) {
                item.find(':input').each(function (i, e) {
                    $(this).attr('lay-verify',validateStr);
                })
            }
        }
        var exportFunc=function (rowData, params) {
            var cptId = rowData.id;
            var divId ='did_' + Date.now() + "_" + params.index;

            rowData['divId']=divId;
            params.exportMap[divId]=rowData;
            var html = undefined;
            if(cptId=='hidden'){
                html = $($('#cpts_items').find("#" + cptId).find('input').get(0).outerHTML);
                html.attr('id',divId);
                if(!that.isEmpty(rowData.name))html.attr('name',rowData.name);
                if(!that.isEmpty(rowData.defValue))html.val(rowData.defValue);
                return html;
            }
            html = $($('#cpts_items').find("#" + cptId).get(0).outerHTML);
            html.attr('id', divId).attr('cpt_id', cptId);
            that.propertiesMap[divId] = rowData;
            //parentNode.append(html);

            params.index++;

            if (cptId != 'groupLayout') {
                if (cptId == 'editor') html.find('.editor').html('');
                that.createSortableItemUI(html, {isInitJs: false});
                html.removeAttr('rename');
                
                createValidateFunc(rowData,html);
                return html;
            }

            var subItemHtml = $('#cpts_items').find("#" + cptId).children().get(0).outerHTML;
            html.html('');
            var children = rowData.children;
            if(children!=undefined) {
                for (var i = 0; i < children.length; i++) {
                    var itemHtml = $(subItemHtml);
                    var sortItemId = 'sub_' + new Date().getTime() + '_' + i;
                    itemHtml.attr('id', sortItemId);
                    itemHtml.removeAttr('class').addClass('group-layout-border adminj-col-item layui-col-md' + (12 / rowData.children.length));
                    html.append(itemHtml);
                    var _arrL1 = children[i];
                    for (var j = 0; j < _arrL1.length; j++) {
                        var _arrL2 = _arrL1[j];
                        var childHtml=exportFunc(_arrL2, params);
                        itemHtml.append(childHtml);
                    }
                }
            }
            html.removeAttr('rename');
            return html;
        }

        var exportMap={};//按ID为KEY导出属性
        var params={index:0,exportMap:exportMap},resHtml=$('<form class="layui-form" id="form" lay-filter="form" action=""></form>');
        var exportJSON=that.exportJSON();
        if(exportJSON=='')return '';
        var json=JSON.parse(exportJSON);
        for (var i = 0; i < json.length; i++) {
            var rowData = json[i];
            var itemHtml=exportFunc(rowData,params);
            resHtml.append(itemHtml);
        }
        var js=JSON.stringify(exportMap);
        //js=js.replaceAll("'","\\'");
        js="<script>var _json='"+js+"';<\/script>\r\n";

        return  js+resHtml.get(0).outerHTML;
    }

    AdminJLayuiFormRender.prototype.exportAllHTML = function () {

    }

    AdminJLayuiFormRender.prototype.showLayerTextarea = function (val) {//显示有textarea的弹出层
        layui.layer.open({
            type: 1,
            closeBtn: 1,
            shadeClose: true,
            area: ['80%', '90%'],
            content: '<textarea id="outprint_textarea" style="width: 98%;height: 97%; margin-left: 1%;margin-top: 1%;"></textarea>',//'+val+'
            success: function(layero, index){
                $('#outprint_textarea').text(val);
            }
        });
    }

    AdminJLayuiFormRender.prototype.showImportLayerTextarea = function () {//导入json
        var that=this;
        layui.layer.open({
            type: 1,
            closeBtn: 1,
            shadeClose: true,
            area: ['80%', '90%'],
            content: '<textarea id="outprint_textarea" style="width: 98%;height: 97%; margin-left: 1%;margin-top: 1%;"></textarea>'
            ,btn: ['确定', '取消']
            ,yes: function(index, layero){
                that.importJSON($('#outprint_textarea').val());
                layui.layer.close(index);
            },btn2: function(index, layero){
            }
        });
    }


    var formRender = new AdminJLayuiFormRender();


    var $;
    layui.use(function () {
        $ = layui.$

        try {
            formRender.render();

            $('#exportForm').click(function () {
                var html=formRender.exportToHTML();
                formRender.showLayerTextarea(html);
            });

            $('#importJSON').click(function () {
                formRender.showImportLayerTextarea();
            })

            $('#itemJson').click(function () {
                var json = '';
                $('#sortable').find('.select-sort-item').each(function (i, e) {
                    var divId = $(this).attr('id');
                    json = JSON.stringify(formRender.propertiesMap[divId]);
                });
                formRender.showLayerTextarea(json);

            });

            $('#exportJSON').click(function () {
                var json=formRender.exportJSON();
                formRender.showLayerTextarea(json);
            })

            $('#browseResult').click(function () {
                var res=formRender.exportToHTML();
                $('#resHtml').val(res);
                $('#submitHtml').trigger('click');
            })
            
            var winHeight = $(window).height() - 10;
            if ($('.ds-center').height() < winHeight) {
                $('.ds-center').css('min-height', winHeight-$('.ds-center').css('top'))
            }

        } catch (e) {
            alert("error:" + e)
        }

    });


</script>